package top.ply.messageservice.service.Impl;

import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import top.ply.message.pojo.MsgResult;
import top.ply.message.service.EmailMsgService;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * DubboService注解用于使用Dubbo向Nacos注册服务
 * RefreshScope注解开启配置的动态更新
 */
@Service
@DubboService(interfaceClass = EmailMsgService.class)
@RefreshScope
public class EmailMsgServiceImpl implements EmailMsgService {

    Logger logger = LoggerFactory.getLogger(EmailMsgServiceImpl.class);

    @Autowired
    private JavaMailSender mailSender;

    // 邮件发送者
    @Value("${spring.mail.username}")
    private String sendFrom;

    private static final String EMAIL_REG_EXP = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";

    private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REG_EXP);

    private static final String EMAIL_SEND_TO_KEY = "send_to";

    private static final String EMAIL_SUBJECT_KEY = "subject";

    private static final String EMAIL_CONTENT_KEY = "content";

    @Override
    public boolean sendVerifyCode(String email, String code) {

        logger.info("Accept send verify code request to email: " + email);

        logger.info("Start check parameter");

        // 模板模式，先规定工作流程，然后在其他方法中实现
        if (!checkParams(email, code)) {
            return false;
        } else {
            logger.info("Wrapping data");
            Map<String, String> sendingData = wrapVerifyCodeData(email, code);
            return sendMail(sendingData);
        }
    }

    @Override
    public MsgResult getMsgResult(String msgID) {
        return null;
    }

    boolean checkParams(String email, String code) {
        if (!EMAIL_PATTERN.matcher(email).matches()) {
            return false;
        } else {
            return StringUtils.hasText(code);
        }
    }

    Map<String, String> wrapVerifyCodeData(String email, String code) {
        // 一些公共参数可以封装成一个方法来做公共封装
        Map<String, String> commonData = wrapCommonData(email);
        commonData.put(EMAIL_SEND_TO_KEY, email);
        commonData.put(EMAIL_SUBJECT_KEY, "验证码下发通知");
        String content = "您的验证码是: " + code + "\n5分钟内有效";
        commonData.put(EMAIL_CONTENT_KEY, content);
        return commonData;
    }

    Map<String, String> wrapCommonData(String email) {
        // emm，暂时还没有，先放这里吧
        return new HashMap<>();
    }

    boolean sendMail(Map<String, String> data) {
        logger.info("Start to send Email");
        SimpleMailMessage smm = new SimpleMailMessage();
        smm.setFrom(sendFrom);
        smm.setTo(data.get(EMAIL_SEND_TO_KEY));
        smm.setSentDate(new Date());
        smm.setSubject(data.get(EMAIL_SUBJECT_KEY));
        smm.setText(data.get(EMAIL_CONTENT_KEY));
        try {
            mailSender.send(smm);
            return true;
        } catch (Exception e) {
            // 抛出异常，之后AOP做日志可以用
            logger.error("Failed to send email to " + data.get(EMAIL_SEND_TO_KEY));
            e.printStackTrace();
            throw e;
        }
    }
}
